
#include "constant.h"
#include "log.h"
#include "request.h"
#include "logic.h"
#include <stdlib.h>
#include <string.h>

int deal_request(struct request *req);
const char *get_value(const char *key);

#define END_CLI_THREAD(x) do { free_request(x); return (void *)0; } while(0)

void *client_thread(void *arg)
{
	struct request *req;

	req = (struct request *)arg; 
	if (!req)
		END_CLI_THREAD(req);
	
	
	
	if (BS_ERROR == recv_from_req(req))	
		END_CLI_THREAD(req);

	LOG_DEBUG("\n------recv:------------\n"
				"%s\n---------------------\n",req->recv_buff);
	
	
	if (BS_ERROR == deal_request(req)) {
		LOG_ERR("client thread error accured\n");
		req->erroraccur = 1;
	}

	END_CLI_THREAD(req);
}

void client_thread_win32(void *arg)
{
	client_thread(arg);
}

int deal_request(struct request *req)
{
	const char *path;

	if ( BS_OK != parse_url(req))
		return BS_ERROR;

	if ( BS_OK != parse_method(req))
		return BS_ERROR;

	if ( !strcmp(req->url, "/user_check"))
		return user_check(req);
	else if (path = get_value(req->url) )
		return get_html(req, path);
	else
		get_error_html(req);
	return BS_ERROR;
}



/*	recv from the req->fd
*	failure: BS_ERROR  recv may failed
*	allocate req->recv_buff
+   no input check , no free!
*/
int recv_from_req(struct request *req) 
{
	int rtn;
	int count = 0;
	char buff[LEN4096];
	LOG_DEBUG("recv_from_req begin..\n");

	
	while(1) {
		rtn = recv(req->fd, buff, LEN4096 - 1, 0);
		if ( rtn == -1 ) 
		{
			SYS_ERR("recv");
			break; 
		}
		
		if ( 0 == rtn)
			return BS_ERROR;

		count += rtn;

		req->recv_buff = (char *)realloc(req->recv_buff, count + 1);
		if (!req->recv_buff)
			return BS_ERROR;

		memcpy(req->recv_buff + count - rtn, buff, rtn);
		req->recv_buff[count] = 0;

		break;
		
	}
	LOG_DEBUG("recved buff: \n%s\n", req->recv_buff);
	LOG_DEBUG("recv_from_req end..\n");
 	if ( -1 == rtn )
 		return BS_ERROR;
	
	return BS_OK;
}



/* no input check ! 
*  return BS_OK | BS_ERROR
*/
int send_buff(const struct request *req, const char *buff,int len)
{
	int rtn = 0;

	LOG_DEBUG("send_buff begin: %s\n", buff);

	for (;;) {
		
		rtn += send(req->fd, buff + rtn, len, 0);
		if (-1 == rtn) {
			LOG_ERR("send failed\n");	
			return BS_ERROR;
		}	
		
		if (rtn == 0)
			break;
		
		len -= rtn;
		
		if (len <= 0)
			break;
		
	}
	return BS_OK;

}
